<?php    
/*
 * Composes a MIME-mail messages according to RFCs 2045-2049.
 */

class Core_IO_Mail {

    private $objSender;
    private $arrRecievers = array();
    private $arrCCs = array();
    private $arrBCCs = array();
    private $objReplyTo = null;
    private $strSubject;
    private $arrTextMessage;
    private $arrHTMLMessage;
    private $arrAttachments = array();

    /**
     *
     * @param Core_IO_SMTPConnection $SMTPConnection Uses mail() if no SMTP connection is present.
     */
    function __construct () {
        
    }

    public function setSender ( $strAddress, $strName = null ) {
        $this->objSender = new Core_IO_Mail_Address();
        $this->objSender->Name = $strName;
        $this->objSender->Address = $strAddress;
    }

    public function addReciever ( $strAddress, $strName = null ) {
        $objReciever = new Core_IO_Mail_Address();
        $objReciever->Name = $strName;
        $objReciever->Address = $strAddress;
        $this->arrRecievers[] = $objReciever;
    }

    public function addCC ( $strAddress, $strName = null ) {
        $objCC = new Core_IO_Mail_Address();
        $objCC->Name = $strName;
        $objCC->Address = $strAddress;
        $this->arrCCs[] = $objCC;
    }

    public function addBCC ( $strAddress, $strName = null ) {
        $objBCC = new Core_IO_Mail_Address();
        $objBCC->Name = $strName;
        $objBCC->Address = $strAddress;
        $this->arrBCCs[] = $objBCC;
    }

    public function setReplyTo ( $strAddress, $strName = null ) {
        $this->objReplyTo = new Core_IO_Mail_Address();
        $this->objReplyTo->Name = $strName;
        $this->objReplyTo->Address = $strAddress;
    }

    public function setSubject ( $strSubject ) {
        $this->strSubject = $strSubject;
    }

    public function setTextMessage ( $strMessage, $strCharset = "ISO-8859-1" ) {
        $this->arrTextMessage[0] = $strMessage;
        $this->arrTextMessage[1] = $strCharset;
    }

    public function setHTMLMessage ( $strMessage, $strCharset = "ISO-8859-1" ) {
        $this->arrHTMLMessage[0] = $strMessage;
        $this->arrHTMLMessage[1] = $strCharset;
    }

    public function addAttachment ( $strFilename ) {

        $objAttachment = new Core_IO_Mail_Attachment();

        // TODO: Fill $objAttachment.

        $this->arrAttachments[] = $objAttachment;

    }

    public function compose () {

        // TODO: Fix the character encoding of addresants names and subject.


        // The following are described by RFC 822.

        $strHeaders = "From: " . $this->objSender->getMIMEFormated() . "\r\n";

        $strHeaders .= "To: ";
        for ( $i = 0; $i < count( $this->arrRecievers ); $i++ ) {
            $strHeaders .= $this->arrRecievers[$i]->getMIMEFormated();
            if ( $i != count( $this->arrRecievers ) - 1 ) {
                $strHeaders .= ",\r\n ";
            }
        }
        $strHeaders .= "\r\n";

        if ( count( $this->arrCCs ) ) {
            $strHeaders .= "Cc: ";
            for ( $i = 0; $i < count( $this->arrCCs ); $i++ ) {
                $strHeaders .= $this->arrCCs[$i]->getMIMEFormated();
                if ( $i != count( $this->arrCCs ) ) {
                    $strHeaders .= ",\r\n ";
                }
            }
            $strHeaders .= "\r\n";
        }

        if ( count( $this->arrBCCs ) ) {
            $strHeaders .= "Bcc: ";
            for ( $i = 0; $i < count( $this->arrBCCs ); $i++ ) {
                $strHeaders .= $this->arrBCCs[$i]->getMIMEFormated();
                if ( $i != count( $this->arrBCCs ) ) {
                    $strHeaders .= ",\r\n ";
                }
            }
            $strHeaders .= "\r\n";
        }

        if ( isset( $objReplyTo ) ) {
            $strHeaders .= "Reply-To: " . $this->objReplyTo->getMIMEFormated() . "\r\n";
        }

        $strHeaders .= "Subject: " . $this->strSubject . "\r\n";


        // MIME stuff, described by RFC 2045 through 2049.

        $strHeaders .= "MIME-Version: 1.0" . "\r\n";

        $strBoundary = md5(uniqid(rand(), true));
        $strHeaders .= "Content-Type: multipart/alternative; boundary=" . $strBoundary . "\r\n";
        $strHeaders .= "\r\n";

        if ( $this->arrTextMessage ) {

            $strHeaders .= "--" . $strBoundary . "\r\n";
            $strHeaders .= "Content-Type: text/plain; charset=" . $this->arrTextMessage[1] . "\r\n";
            $strHeaders .= "Content-Transfer-Encoding: base64\r\n\r\n";
            $strHeaders .= chunk_split( base64_encode( $this->arrTextMessage[0] ) );
            $strHeaders .= "\r\n\r\n";

        }

        if ( $this->arrHTMLMessage ) {

            $strHeaders .= "--" . $strBoundary . "\r\n";
            $strHeaders .= "Content-Type: text/html; charset=" . $this->arrHTMLMessage[1] . "\r\n";
            $strHeaders .= "Content-Transfer-Encoding: base64\r\n\r\n";
            $strHeaders .= chunk_split( base64_encode( $this->arrHTMLMessage[0] ) );
            $strHeaders .= "\r\n\r\n";

        }

        return $strHeaders;

   }

    public function send ( Core_IO_SMTPServerInformation $SMTPServerInformation = null ) {

        if ( $SMTPServerInformation ) {

            // Send using an SMTP server.

            $SMTPConnection = new Core_IO_SMTPConnection( $SMTPServerInformation );
            $SMTPConnection->setSender( $this->objSender->Address );

            $arrRecievers = array_merge( $this->arrRecievers, $this->arrCCs, $this->arrBCCs );
            foreach ( $arrRecievers as $objReciever ) {
                $SMTPConnection->addReciever( $objReciever->Address );
            }

            $SMTPConnection->setData( $this->compose() );
            $SMTPConnection->close();

        } else {

            // Send using mail().

            mail( "", "", "", $this->compose() );

        }

    }

}

?>